A keychain event is generated when one of the following situations occurs:
If you are interested in receiving keychain events in your application, you must first call the function KCAddCallback to register your callback function. You can specify the keychain events you want to receive in the
eventMask
parameter of the registration function. Once you have registered your function, the Keychain Manager will invoke your callback when the specified keychain event(s) occur. When you no longer want to handle keychain events, call the function KCRemoveCallback to unregister your callback function.
The simplest approach to handling keychain events is to ignore them while Keychain Manager dialog boxes are open. If you do this, Keychain dialog boxes can't be moved or resized by the user. If you want to make these dialog boxes movable and resizable, you can write a simple keychain event handling callback function. You should set the bit specified by the mask constant
kSystemKCEvent
in the
eventMask
parameter to ensure that window updating occurs correctly.
Since Keychain Manager functions are synchronous, you may want to create a callback function that receives keychain idle events if your application is not threaded. Synchronous functions do not return control to your application until they are complete. In this case, your callback will be called periodically until the Keychain function completes. Your application must call the Thread Manager function
YieldToAnyThread
or the
Event Manager function
WaitNextEvent
when an idle event is generated. If your callback does not specify that it will handle idle events, the Keychain Manager will periodically call the function
YieldToAnyThread.
When a keychain event occurs, the Keychain Shared Library calls your callback function. Allocating memory or calling Mac OS Toolbox functions that do so is unsafe in this circumstance, unless the event is an idle event. When an idle event occurs, your application is free to make Toolbox calls and perform memory allocation.
Listing 4-2 shows how your application might register your callback function to handle keychain events. Listing 4-3 illustrates a sample keychain event handling callback function.
Listing 4-2 Registering your callback function
OSStatus RegisterMyCallBackProc (Ptr myDataPtr) { OSStatus status = noErr; static KCCallbackUPP myCallbackUPP = nil; if (!myCallbackUPP) { // create a UPP for callback function myCallbackUPP = NewKCCallbackProc(MyCallbackProc); } status = KCAddCallback(myCallbackUPP, kcEveryEvent, myDataPtr); return (status); }
Listing 4-3 Creating your own callback function
pascal void MyCallbackProc ( KCEvent inEvent, KCCallbackInfo *info, void *userContext) { MyDataPtrType myDataPtr = (MyDataPtrType) userContext; if (inEvent == kcIdleEvent) { YieldToAnyThread(); } else if (myDataPtr != nil) { // it may not be safe to allocate or move memory here, // so you may want to queue the event for later processing myDataPtr->event = inEvent; myDataPtr->item = inInfo->Item; myDataPtr->gotAnEvent = True; } }